//201492287 张翔州
//实现了浮点数和-和/以及错误报告
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
//E -> TE' 
//E' -> +TE' | -TE'|e
//T -> FT'
//T' -> *FT' | /FT'| e
//F -> NUM | (E)
//FIRST(E) = {NUM, LEFTB}
//FIRST(E') = {PLUS,MIN,e}
//FIRST(T) = {NUM, LEFTB}
//FIRST(T') = {MULT,DIV e}
//FIRST(F) = {NUM, LEFTB}
//FOLLOW(E) = {$, RIGHTB}
//FOLLOW(E') = {$, RIGHTB}
//FOLLOW(T) = {PLUS,MIN RIGHTB, $}
//FOLLOW(T') = {PLUS,MIN RIGHTB, $}
//FOLLOW(F) = {MULT, PLUS, DIV,MIN,RIGHTB, $}

enum TOKEN {PLUS,MIN, MULT,DIV, NUM, END, ERR, LEFTB, RIGHTB};
char lookahead;
enum TOKEN token;
float num;
int error = 0;
FILE *fp;

void lexical(FILE *fp);
int match(enum TOKEN x);
float E();
float E_();
float T();
float T_();
float F();


//return 0 if success, return 1 otherwise
int match(enum TOKEN x) {
	if(token == x) {
		lexical(fp);
		return 0;
	} else {
		error = 1;
		return 1;
	}
}

//E -> TE' 
float E() {
	float a=0;
    float b=0;
	if(token==NUM||token==LEFTB)
	{
		a=T();
	    b=E_();
		return a+b;
	}
    else error=1;
	return 0;
}

//E_ -> +TE'|-TE'|e  e表示空串遇到空时候处理 
float E_() {
	float a=0;
	float b=0;
	if(token==PLUS)
	{
		match(token);
		a=T();
		b=E_();
		return a+b;
	}
	else if(token==MIN)
	{
		match(token);
		a=T();
		b=E_();
		return b-a;
	}
	else if(token==RIGHTB)
		 return 0;
	else if(token==END)
	{
		return 0;
	}
	else error=1;
	return 0;
}

//T -> FT'
float T(){
	float a=0;
	float b=1;
	if(token==NUM||token==LEFTB)
	{
	a=F();
	b=T_();
	return a*b;
	}
	else
		error=1;
	return 0;
}


//T' -> *FT' | /FT'|e
float T_() {
	float a=0;
	float b=1;
	if(token==MULT)
	{
		match(token);
		a=F();
		b=T_();
		return a*b;
	}
	else if(token==DIV)
	{
		match(token);
		a=F();
		b=T_();
		return b/a;
	}

	else if(token==PLUS||token==RIGHTB||token==MIN)
	{
		return 1;
	}
	else if(token==END)
		return 1;
	else
		error=1;
	return 1;
}

//F -> NUM | (E)
float F() {
	float a=0;
	if(token==NUM)
	{ 
		a=num;
		match(token);
		if(token==NUM)
		{
			printf("error at %f",num);
			getchar();
			exit(0);
		}
		return a;
	}
	else if(token==LEFTB)
	{
        match(token);
		a=E();
		if(token==RIGHTB)
			match(token);
		else
		{
			printf("unmatched bracket");
			getchar();
			exit(0);
		}
		return a;
	}
	else
		error=1;
	return 0;
}





void lexical(FILE *fp) {

	lookahead = getc(fp);
	num = 0;

	while(lookahead == ' ' || lookahead == '\t' || lookahead == '\n') {
		lookahead = getc(fp);
	}

	if(isdigit(lookahead)) {
		num = 0;
		while(isdigit(lookahead)) {
			token = NUM;
			num = num * 10 + lookahead - '0';
			lookahead = getc(fp);
		}
		if(lookahead=='.')
		{
			int i=10;
			lookahead = getc(fp);
			
			while(isdigit(lookahead))
			{
				num=num+(lookahead-'0')/(i*1.0);
				i=i*10;
				lookahead = getc(fp);
			}
		}
		ungetc(lookahead, fp);
		return;
	} else if (lookahead == '+') {
		token = PLUS;
		return;
	}else if(lookahead=='-'){
		token=MIN;
	    return;
	} else if (lookahead == '*') {
		token = MULT;
		return;
	} else if(lookahead=='/'){
		token= DIV;
		return;
	}else if(lookahead == EOF) {
		token = END;
		return;
	}else if(lookahead == '(') {
		token = LEFTB;
		return;
	} else if(lookahead == ')') {
		token = RIGHTB;
		return;
	} else {
		error = 1;
		token = ERR;
		return;
	}
}

int main(int argc, char **argv) {
	int  res = 0;
	if(argc < 2) {
		printf("insufficient arguments");
		return 1;
	}
	fp = fopen(argv[1], "r");
	lexical(fp);
	res = E();
	if(!error) {
		printf("%d\n", res);
	} else {
		printf("There are errors\n");
	}
	fclose(fp);
	return 0;
}
